package org.jdsm.flow.gxt.users.client.widgets.role;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.data.client.loader.HttpProxy;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.loader.LoadResultListStoreBinding;
import com.sencha.gxt.data.shared.loader.PagingLoader;
import com.sencha.gxt.data.shared.loader.TreeLoader;
import com.sencha.gxt.data.shared.writer.JsonWriter;
import com.sencha.gxt.dnd.core.client.DND;
import com.sencha.gxt.dnd.core.client.GridDragSource;
import com.sencha.gxt.dnd.core.client.GridDropTarget;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import org.jdsm.flow.gxt.users.client.UserAutoBeanFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * User: mikom
 * Date: 12/6/12
 * Time: 7:38 PM
 */
public class RoleUserGrid implements IsWidget {


    private String buildFullGridPath = "data/users.json";
    private String buildCurrentGridPath = "data/users.json";
    private String saveDataPath = "data/response.json";

    PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult> currentLoader;
    PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult> fullLoader;

    TreeLoader<UserAutoBeanFactory.Response> saveLoader;

    Grid<UserAutoBeanFactory.User> currentGrid;

    private VerticalPanel panel;
    private UserAutoBeanFactory factory;


    public RoleUserGrid(UserAutoBeanFactory factory, String fullPath, String currentPath, String saveDataPath) {
        panel = new VerticalPanel();
        this.factory = factory;
        this.buildFullGridPath = fullPath;
        this.buildCurrentGridPath = currentPath;
        this.saveDataPath = saveDataPath;
    }
/*
    public Grid<Role> getGrid(){
        return currentGrid;
    }*/


    protected PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult> buildLoader(String uri) {

        UserAutoBeanFactory.UserDataRecordJsonReader reader =
                new UserAutoBeanFactory.UserDataRecordJsonReader(factory);

        RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, uri);
        builder.setHeader("content-type", "application/json");
        HttpProxy<UserAutoBeanFactory.PagingListLoadConfig> proxy = new HttpProxy<UserAutoBeanFactory.PagingListLoadConfig>(builder);
        JsonWriter<UserAutoBeanFactory.PagingListLoadConfig> writer = new JsonWriter<UserAutoBeanFactory.PagingListLoadConfig>(factory, UserAutoBeanFactory.PagingListLoadConfig.class);
        proxy.setWriter(writer);

        PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult> loader =
                new PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult>(proxy, reader);

        loader.useLoadConfig(factory.pagingLoadConfig().as());
        loader.setLimit(10);
        loader.setRemoteSort(true);

        return loader;
    }

    public PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult> getCurrentLoader() {
        return currentLoader;
    }

    public PagingLoader<UserAutoBeanFactory.PagingListLoadConfig, UserAutoBeanFactory.UserPagingLoadResult> getFullLoader() {
        return fullLoader;
    }

    protected Grid<UserAutoBeanFactory.User> buildFullGrid() {


        fullLoader = buildLoader(buildFullGridPath);

        UserAutoBeanFactory.UserProperties props = GWT.create(UserAutoBeanFactory.UserProperties.class);

        ListStore<UserAutoBeanFactory.User> store = new ListStore<UserAutoBeanFactory.User>(props.key());
        fullLoader.addLoadHandler(new LoadResultListStoreBinding<UserAutoBeanFactory.PagingListLoadConfig,
                        UserAutoBeanFactory.User,
                        UserAutoBeanFactory.UserPagingLoadResult>(store));

        final ColumnConfig<UserAutoBeanFactory.User, String> columnName =
                new ColumnConfig<UserAutoBeanFactory.User, String>(props.name(), 200, "Full roles");

        List<ColumnConfig<UserAutoBeanFactory.User, ?>> l = new ArrayList<ColumnConfig<UserAutoBeanFactory.User, ?>>();
        l.add(columnName);

        ColumnModel<UserAutoBeanFactory.User> cm = new ColumnModel<UserAutoBeanFactory.User>(l);

        final Grid<UserAutoBeanFactory.User> grid = new Grid<UserAutoBeanFactory.User>(store, cm);
        grid.getView().setForceFit(true);
        grid.setLoader(fullLoader);
        grid.setLoadMask(true);
        grid.setBorders(true);
        grid.getView().setEmptyText("No result found");

        return grid;
    }


    protected Grid<UserAutoBeanFactory.User> buildCurrentGrid() {
        currentLoader = buildLoader(buildCurrentGridPath);

        UserAutoBeanFactory.UserProperties props = GWT.create(UserAutoBeanFactory.UserProperties.class);

        ListStore<UserAutoBeanFactory.User> store = new ListStore<UserAutoBeanFactory.User>(props.key());
        currentLoader.addLoadHandler(new LoadResultListStoreBinding<UserAutoBeanFactory.PagingListLoadConfig,
                UserAutoBeanFactory.User,
                UserAutoBeanFactory.UserPagingLoadResult>(store));

        final ColumnConfig<UserAutoBeanFactory.User, String> columnName = new ColumnConfig<UserAutoBeanFactory.User, String>(props.name(), 200, "Current roles of user");

        List<ColumnConfig<UserAutoBeanFactory.User, ?>> l = new ArrayList<ColumnConfig<UserAutoBeanFactory.User, ?>>();
        l.add(columnName);

        ColumnModel<UserAutoBeanFactory.User> cm = new ColumnModel<UserAutoBeanFactory.User>(l);

        final Grid<UserAutoBeanFactory.User> grid = new Grid<UserAutoBeanFactory.User>(store, cm);
        grid.getView().setForceFit(true);
        grid.setLoader(currentLoader);
        grid.setLoadMask(true);
        grid.setBorders(true);
        grid.getView().setEmptyText("No result found");


        return grid;

    }

    public void saveData() {
        UserAutoBeanFactory.ResponseDataRecordJsonReader reader =
                new UserAutoBeanFactory.ResponseDataRecordJsonReader(factory, UserAutoBeanFactory.Response.class);

        String path = saveDataPath;

        RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, path);
        HttpProxy<UserAutoBeanFactory.Response> proxy = new HttpProxy<UserAutoBeanFactory.Response>(builder);
        JsonWriter<UserAutoBeanFactory.Response> writer =
                new JsonWriter<UserAutoBeanFactory.Response>(factory, UserAutoBeanFactory.Response.class);
        proxy.setWriter(writer);
        saveLoader = new TreeLoader<UserAutoBeanFactory.Response>(proxy, reader);
    }

    public void saveAction(UserAutoBeanFactory.Role selectedRole) {
        UserAutoBeanFactory.UserResponse config = (UserAutoBeanFactory.UserResponse) saveLoader.getLastLoadConfig();
        if (config == null) {
            config = factory.userResponseResult().as();
        }
        config.setRole(selectedRole);

        for (UserAutoBeanFactory.User record : currentGrid.getStore().getAll()) {
            config.setUser(record);
            saveLoader.load(config);
        }

        currentGrid.getStore().commitChanges();
    }

    public void loadDataByRole(UserAutoBeanFactory.Role role) {
        UserAutoBeanFactory.PagingListLoadConfig config = getCurrentLoader().getLastLoadConfig();
        UserAutoBeanFactory factory = GWT.create(UserAutoBeanFactory.class);
        if (config == null) {
            config = factory.pagingLoadConfig().as();
        }
        UserAutoBeanFactory.Paging paging = config.getPaging();
        if (paging == null) {
            paging = factory.paging().as();
            config.setPaging(paging);
        }
        config.setRole(role);
        getCurrentLoader().load(config);
        getFullLoader().load();
    }


    @Override
    public Widget asWidget() {

        panel.addAttachHandler(new AttachEvent.Handler() {
            @Override
            public void onAttachOrDetach(AttachEvent event) {
//                panel.mask("Please wait");
            }
        });

//        HorizontalLayoutContainer container = new HorizontalLayoutContainer();
        HorizontalPanel container = new HorizontalPanel();


        currentGrid = buildCurrentGrid();

        final Grid<UserAutoBeanFactory.User> fullGrid = buildFullGrid();

        new GridDragSource<UserAutoBeanFactory.User>(currentGrid);
        new GridDragSource<UserAutoBeanFactory.User>(fullGrid);

        final GridDropTarget<UserAutoBeanFactory.User> currentDndTarget = new GridDropTarget<UserAutoBeanFactory.User>(currentGrid);
        currentDndTarget.setFeedback(DND.Feedback.INSERT);

        final GridDropTarget<UserAutoBeanFactory.User> fullDndTarget = new GridDropTarget<UserAutoBeanFactory.User>(fullGrid);
        fullDndTarget.setFeedback(DND.Feedback.INSERT);

        container.add(fullGrid);
        container.add(currentGrid);

        panel.add(container);

        return panel;
    }
}
